<!-- This benchmark run a lot of small benchmarks that are defined with a karma-like sytax
  in canvas_perf.js
-->
<!DOCTYPE html>
<html>
<head>
  <title>CanvasKit SKP Perf</title>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="/static/canvaskit.js" type="text/javascript" charset="utf-8"></script>
  <script src="/static/benchmark.js" type="text/javascript" charset="utf-8"></script>
  <script src="/static/canvas_perf.js" type="text/javascript" charset="utf-8"></script>
  <style type="text/css" media="screen">
    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
  <main>
    <button id="start_bench">Start Benchmark</button>
    <br>
    <canvas id=anim width=600 height=600 style="height: 600px; width: 600px;"></canvas>
  </main>
  <script type="text/javascript" charset="utf-8">
    const WIDTH  = 600;
    const HEIGHT = 600;
    const WARM_UP_FRAMES = 5;
    // Keeping this a little lower because this test runs many smaller tests,
    // each for this many frames, which could add up to a long time.
    const MAX_FRAMES = 51;

    // Any external files needed by tests in canvas_perf.js must be listed here.
    // And checked in under canvas_perf_assets/
    // tests may then fetch them from ctx.files['filename']
    const testDataFiles = [
      'test_64x64.png',
      'test_512x512.png',
      'test_1500x959.jpg',
      'Roboto-Regular.ttf',
      'Roboto-Regular.woff',
      'Roboto-Regular.woff2',
    ];

    (function() {
      const filePromises = [];
      for (const filename of testDataFiles) {
        filePromises.push(fetch('/static/assets/'+filename).then((resp) => {
          return resp.arrayBuffer(); // this is also a promise.
        }));
      }
      const externals = Promise.all(filePromises).then((results) => {
        const files = {};
        let i=0;
        for (const bytes of results) {
          // store them by name
          files[testDataFiles[i]] = bytes;
          i++;
        }
        return files;
      });

      const loadCanvasKit = CanvasKitInit({
        locateFile: (file) => '/static/' + file,
      });

      Promise.all([loadCanvasKit, externals]).then(([CanvasKit, externalFiles]) => {
        const urlSearchParams = new URLSearchParams(window.location.search);
        let glversion = 2;
        if (urlSearchParams.has('webgl1')) {
          glversion = 1;
        }
        let surface = getSurface(CanvasKit, glversion);
        if (!surface) {
          console.error('Could not make surface', window._error);
          return;
        }

        document.getElementById('start_bench').addEventListener('click', async () => {
          window._perfData = {};

          // canvas_perf.js should have defined an array called tests whose objects have:
          //  setup:    A function called once before testing begins, it is expected to make its
          //            own canvas and put it in ctx.
          //  test:     A function called to draw one frame
          //  teardown: A function called after testing finishes
          //  description:     A human readable description
          //  perfkey:  A key used to save the results in perf.skia.org.
          //
          // For quick local bench testing, there is also an array called onlytests. This way
          // a developer can replace tests.push with onlytests.push to just run one or two
          // performance benchmarks they care about.
          let testsToRun = tests;
          if (onlytests.length) {
            testsToRun = onlytests;
          }

          for (const t of testsToRun) {
            let ctx = {
              'surface': surface,
              'files': externalFiles,
            };
            console.log('Benchmarking "' + t.description + '"');
            t.setup(CanvasKit, ctx);
            function draw() {
              t.test(CanvasKit, ctx);
            }
            // TODO(nifong): is it ok to keep re-using the surface?
            results = await startTimingFrames(draw, surface, WARM_UP_FRAMES, MAX_FRAMES);
            t.teardown(CanvasKit, ctx);
            window._perfData[t.perfKey] = results;

            // Delete and re-create surface between tests, to prevent the possibility of
            // interference between them through the state of surface, the gl context, or things
            // that are keyed by the surface's gen id.
            surface.delete();
            surface = getSurface(CanvasKit, glversion);

            // TODO(nifong): provide a function similar to startTimingFrames for timing
            // non-visual tests.
          }
          surface.delete();
          window._perfDone = true;
        });
        console.log('Perf is ready');
        window._perfReady = true;
      });
    }
  )();

  </script>
</body>
</html>
